//
//  ViewController.swift
//  GraphicDemo
//
//  Created by Riven on 2020/11/9.
//  Copyright © 2020 Riven. All rights reserved.
//

import UIKit
import CoreGraphics

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let testView = CGView(frame: CGRect(x: 0, y: UIScreen.main.bounds.height / 4, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width))
        view.addSubview(testView)
    }
    
}

class CGView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func draw(_ rect: CGRect) {
        guard let ct = UIGraphicsGetCurrentContext() else {
            return
        }
        
//        drawLine()
//        drawLineWithContext()
//        clipPathTest()
//        drawIntersects()
//        drawBezierCurve()
        
//        drawWithGState()
        
//        drawWithScaleCTM()
//        drawWithTranslateCTM(ct: ct)
//        drawWithRatateGTM(ct: ct)
//        drawWithSetBlendMode(ct: ct)
//        drawWithReplacePahtWithStrokedPath(ct: ct)
//        drawWithCopyPath(ct: ct)
        
//        drawWithLineSegment(ct: ct)
        
//        drawShadow(ct: ct)
        drawRectWithBezier(ct: ct)
    }

    // MARK: - Bezier Path
    func drawRectWithBezier(ct: CGContext) {
        ct.setStrokeColor(UIColor.yellow.cgColor)
        let path = UIBezierPath()
        path.lineWidth = 4
        path.move(to: CGPoint(x: 10, y: 10))
        path.addLine(to: CGPoint(x: 80, y: 60))
        path.addLine(to: CGPoint(x: 120, y: 20))
        path.stroke()
    }
    
    // MARK: -
    func drawShadow(ct: CGContext) {
        ct.setFillColor(UIColor.red.cgColor)
        ct.addRect(CGRect(x: 100, y: 100, width: 100, height: 100))
        
//        ct.setShadow(offset: CGSize(width: 4, height: 4), blur: 0)
        ct.setShadow(offset: CGSize(width: -1, height: 1), blur: 0.1, color: UIColor.yellow.cgColor)
        ct.fillPath()
    }
    
    func drawWithLineSegment(ct: CGContext) {
        let pa = CGPoint(x: 100, y: 50)
        let pb = CGPoint(x: 200, y: 50)
        let pc = CGPoint(x: 100, y: 70)
        let pd = CGPoint(x: 200, y: 70)
        let pe = CGPoint(x: 100, y: 90)
        let pf = CGPoint(x: 200, y: 90)
        let pg = CGPoint(x: 100, y: 110)
        let ph = CGPoint(x: 200, y: 110)

        ct.setLineWidth(4)
        ct.setStrokeColor(UIColor.yellow.cgColor)
        let pList = [pa, pb, pc, pd, pe, pf, pg, ph]
        ct.strokeLineSegments(between: pList)
    }
    
    func drawWithCopyPath(ct: CGContext) {
        let width = UIScreen.main.bounds.width
        ct.addArc(center: CGPoint(x: 200, y: 200), radius: 140, startAngle: radians(angle: 45), endAngle: radians(angle: 135), clockwise: true)
        
        let cpPath = ct.path?.copy()
        
        ct.setStrokeColor(UIColor.yellow.cgColor)
        ct.setLineWidth(14)
        ct.strokePath()
        
        ct.addPath(cpPath!)
//        ct.setLineWidth(4)
        ct.replacePathWithStrokedPath()
        ct.clip()
        ct.setFillColor(UIColor.red.cgColor)
        ct.fill([CGRect(x: 0, y: 0, width: width, height: width)])
    }
    
    func drawWithReplacePahtWithStrokedPath(ct: CGContext) {
        ct.setStrokeColor(UIColor.yellow.cgColor)
        ct.setLineWidth(24)
        ct.move(to: CGPoint(x: 30, y: 30))
        ct.addLine(to: CGPoint(x: 200, y: 120))
        
        ct.replacePathWithStrokedPath()
        ct.setLineWidth(14)
        
        ct.strokePath()
    }
 
    func drawWithSetBlendMode(ct: CGContext) {
        var rect = bounds
        ct.setFillColor(UIColor.yellow.cgColor)
        ct.addRect(rect)
        ct.fillPath()
        
        ct.setBlendMode(.clear)
        rect = CGRect(x: 100, y: 100, width: 100, height: 100)
        ct.addRect(rect)
        ct.fillPath()
    }

    /**
     度数转弧度：弧度 = 度数 × (π / 180)
     弧度转度数：度数 = 弧度 × (180 / π)
     */
    
    func radians(angle: Double) -> Double {
        angle * Double.pi / 180
    }
    func drawWithRatateGTM(ct: CGContext) {
        ct.setFillColor(UIColor.yellow.cgColor)
        let radians: Double = 45 * Double.pi / 180
        ct.rotate(by: radians)
        ct.fill(CGRect(x: 100, y: 0, width: 100, height: 100))
    }
    
    // 平移坐标系统，平移对象 坐标。
    func drawWithTranslateCTM(ct: CGContext) {
        ct.setFillColor(UIColor.yellow.cgColor)
        ct.fill(CGRect(x: 0, y: 0, width: 100, height: 100))
        ct.translateBy(x: 110, y: 110)
        ct.setFillColor(UIColor.red.cgColor)
        ct.fill(CGRect(x: 100, y: 0, width: 100, height: 100))
    }
    
    func drawWithScaleCTM() {
        guard let ct = UIGraphicsGetCurrentContext() else {
            return
        }
        
        ct.setFillColor(UIColor.yellow.cgColor)
        ct.fill(CGRect(x: 0, y: 0, width: 100, height: 100))
        ct.scaleBy(x: 0.5, y: 0.5)
        ct.setFillColor(UIColor.red.cgColor)
        ct.fill(CGRect(x: 100, y: 100, width: 100, height: 100))
    }
    
    func drawWithGState() {
        guard let ct = UIGraphicsGetCurrentContext() else {
            return
        }
        
        ct.setStrokeColor(UIColor.white.cgColor)
        ct.saveGState()
        
        ct.setStrokeColor(UIColor.yellow.cgColor)
        ct.addEllipse(in: CGRect(x: 40, y: 100, width: 50, height: 50))
        ct.setLineWidth(4)
        ct.strokePath()
        
        ct.restoreGState()
        
        ct.addEllipse(in: CGRect(x: 200, y: 100, width: 50, height: 50))
        ct.strokePath()
    }
    
    func drawBezierCurve() {
        guard let ct = UIGraphicsGetCurrentContext() else {
            return
        }
        
        ct.move(to: CGPoint(x: 94, y: 94))
        ct.addQuadCurve(to: CGPoint(x: 194, y: 194), control: CGPoint(x: 124, y: 294))
        ct.setFillColor(UIColor.yellow.cgColor)
        ct.fillPath()
        
        ct.move(to: CGPoint(x: 204, y: 204))
        ct.addQuadCurve(to: CGPoint(x: 254, y: 254), control: CGPoint(x: 204, y: 384))
        ct.setStrokeColor(UIColor.yellow.cgColor)
        ct.strokePath()
    }
    
    func drawLineWithContext() {
        guard let ct = UIGraphicsGetCurrentContext() else {
            return
        }
        ct.move(to: CGPoint.zero)
        ct.addLine(to: CGPoint(x: 100, y: 100))
        ct.addLine(to: CGPoint(x: 50, y: 150))
        ct.closePath()
        
        ct.setStrokeColor(UIColor.white.cgColor)
        ct.setLineWidth(2)
        ct.setFillColor(UIColor.yellow.cgColor)
        //        ct.fillPath()
        //        ct.strokePath()
        ct.drawPath(using: .fillStroke)
    }
    
    // 裁剪 clip
    func clipPathTest() {
        guard let ct = UIGraphicsGetCurrentContext() else {
            return
        }
        
        let cx = bounds.size.width / 2
        let cy = bounds.size.height / 2
        let ra = min(cx, cy)
        
        let clipPath = CGPath(rect: CGRect(x: 0, y: 0, width: bounds.size.width * 0.3, height: bounds.size.height * 0.5), transform: nil)
        
        ct.addPath(clipPath)
        ct.clip()
        
        ct.addArc(center: CGPoint(x: cx, y: cy), radius: ra, startAngle: 0, endAngle: Double.pi * 2, clockwise: true)
        
        ct.setFillColor(UIColor.yellow.cgColor)
        
        ct.fillPath()
    }
    
    // 绘制相交的路径
    func drawIntersects() {
        guard let ct = UIGraphicsGetCurrentContext() else {
            return
        }
        
        let path = CGMutablePath()
        path.addRect(CGRect(x: 0, y: 0, width: 240, height: 240))
        path.addRect(CGRect(x: 40, y: 40, width: 40, height: 40))
        ct.setFillColor(UIColor.yellow.cgColor)
        let clipPath = CGPath(rect: CGRect(x: 40, y: 40, width: 40, height: 40), transform: nil)
        ct.addPath(clipPath)
        ct.clip()
        ct.addPath(path)
        ct.drawPath(using: .fill)
    }
    
    // 绘制线条
    fileprivate func drawLine() {
        // 获取图形上下文
        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }
        
        // 创建一个矩形
        let rect = bounds
        let drawingRect = rect.insetBy(dx: 3, dy: 3)
        
        // 创建绘制路径
        let path = CGMutablePath()
        path.move(to: CGPoint(x: drawingRect.minX, y: drawingRect.minY))
        path.addLine(to: CGPoint(x: drawingRect.maxX, y: drawingRect.minY))
        //            path.addLine(to: CGPoint(x: drawingRect.maxX, y: drawingRect.maxY))
        //            path.addLine(to: CGPoint(x: drawingRect.minX, y: drawingRect.maxY))
        //            path.addLine(to: CGPoint(x: drawingRect.minX, y: drawingRect.minY))
        
        //            path.addRect(CGRect(x: 20, y: 20, width: 50, height: 50))
        
        context.addPath(path)
        
        // 设置画笔颜色
        context.setStrokeColor(UIColor.red.cgColor)
        
        // 设置画笔宽度
        context.setLineWidth(2)
        
        // 绘制路径
        //            context.strokePath()
        
        // 设置填充颜色
        context.setFillColor(UIColor.orange.cgColor)
        //            context.fillPath()
        context.drawPath(using: .fillStroke)
    }
    
}

